package cn.bird.db.page;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PageInfo<T> {
    private static final long serialVersionUID = 2346364113584310197L;
    /**
     * 结果集
     * NotNull
     */
    private List<T> records;

    /**
     * 总数
     * NotNull
     */
    private Long total;

    /**
     * 当前页
     */
    private Long pageNum;

    /**
     * 每页记录数
     */
    private Long pageSize;

    public static <T> PageInfo<T> fromPage(IPage<T> page) {
        Objects.requireNonNull(page, "page结果不能为空");
        return PageInfo.<T>builder()
                .records(page.getRecords())
                .total(page.getTotal())
                .pageNum(page.getCurrent())
                .pageSize(page.getSize())
                .build();
    }

    public PageInfo<T> setRecords(List<T> records) {
        this.records = records;
        return this;
    }

    public static <T> PageInfo<T> fromPage(IPage<?> page, List<T> data) {
        Objects.requireNonNull(page, "page不能为空");
        Objects.requireNonNull(data, "data不能为空");
        return PageInfo.<T>builder()
                .records(data)
                .total(page.getTotal())
                .pageNum(page.getCurrent())
                .pageSize(page.getSize())
                .build();
    }

    public static <T> PageInfo<T> from(long total, List<T> data) {
        Objects.requireNonNull(data, "data不能为空");
        return PageInfo.<T>builder()
                .records(data)
                .total(total)
                .build();
    }

    @SuppressWarnings("unchecked")
    public <R> PageInfo<R> convert(Function<? super T, ? extends R> trFunction) {
        if (CollUtil.isEmpty(records)) {
            List<R> list = new ArrayList<>();
            return ((PageInfo<R>) this).setRecords(list);
        }
        return ((PageInfo<R>) this).setRecords(
                records.stream()
                        .map(trFunction)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList())
        );
    }
}
